#include "vl_flag.h"

using namespace VL;


/**
 * @Author: CimZzz
 * @Date: 2022-10-25 16:55:30
 * 
 * 构造函数
 * 
 * @param separator 拼接字符串的分隔符
 */
VLFlag::VLFlag(const std::string& separator): flagStr(""), separator(separator) {}

/**
 * @Author: CimZzz
 * @Date: 2022-10-25 17:39:02
 * 
 * 构造函数
 * 构造标志实例, 并指定第一个标志
 * 
 * @param flag 字符串标志
 * @param separator 拼接字符串的分隔符
 */
VLFlag::VLFlag(const char * flag, const std::string& separator): flagStr(""), separator(separator) {
	this->operator+=(flag);
}

/**
 * @Author: CimZzz
 * @Date: 2022-10-25 17:39:02
 * 
 * 构造函数
 * 构造标志实例, 并指定第一个标志
 * 
 * @param flag 字符串标志
 * @param separator 拼接字符串的分隔符
 */
VLFlag::VLFlag(const std::string& flag, const std::string& separator): flagStr(""), separator(separator) {
	this->operator+=(flag);
}

/**
 * @Author: CimZzz
 * @Date: 2022-10-25 17:39:02
 * 
 * 构造函数
 * 构造标志实例, 并指定标志对象作为初始化
 * 
 * @param flagObj 标志对象
 * @param separator 拼接字符串的分隔符
 */
VLFlag::VLFlag(const VLFlag& flagObj, const std::string& separator): flagStr(""), separator(separator) {
	this->operator+=(flagObj);
}

/**
 * @Author: CimZzz
 * @Date: 2022-10-25 17:39:02
 * 
 * 构造函数
 * 构造标志实例, 并指定标志对象作为初始化
 * 
 * @param propPtr 属性指针
 * @param separator 拼接字符串的分隔符
 */
VLFlag::VLFlag(const std::shared_ptr<VLProp>& propPtr, const std::string& separator): flagStr(""), separator(separator) {
	this->operator+=(propPtr);
}


/**
 * @Author: CimZzz
 * @Date: 2022-10-25 17:20:53
 * 
 * 重载等号运算
 * 
 * @param flag 标志
 */
void VLFlag::operator =(const std::string& flag) {
	this->uniqueSet.clear();
	this->uniqueSet.insert(flagStr);
	this->flagStr = flag;
}

/**
 * @Author: CimZzz
 * @Date: 2022-10-25 17:21:20
 * 
 * 重载等号运算
 * 
 * @param flag 标志
 */
void VLFlag::operator =(const char * flag) {
	if(flag == nullptr) {
		return;
	}
	std::string flagStr(flag);
	this->uniqueSet.clear();
	this->uniqueSet.insert(flagStr);
	this->flagStr = flagStr;

}

/**
 * @Author: CimZzz
 * @Date: 2022-10-25 17:21:47
 * 
 * 重载等号运算
 * 
 * @param flagObj 标志对象
 */
void VLFlag::operator =(const VLFlag& flagObj) {
	this->uniqueSet.clear();
	this->uniqueSet.insert(flagObj.uniqueSet.begin(), flagObj.uniqueSet.end());
	this->flagStr = flagObj.flagStr;
}

/**
 * @Author: CimZzz
 * @Date: 2022-10-25 17:21:47
 * 
 * 重载等号运算
 * 
 * @param propPtr 属性指针
 */
void VLFlag::operator =(const std::shared_ptr<VLProp>& propPtr) {
	this->uniqueSet.clear();
	this->flagStr = "";
	this->operator+=(propPtr);
}

/**
 * @Author: CimZzz
 * @Date: 2022-10-25 16:56:32
 * 
 * 重载加法运算
 * 
 * @param flag 标志
 * 
 * @return 当前对象
 */
VLFlag& VLFlag::operator +(const std::string& flag) {
	this->operator+=(flag);
	return *this;
}

/**
 * @Author: CimZzz
 * @Date: 2022-10-25 16:56:32
 * 
 * 重载加法运算
 * 
 * @param flag 标志
 * 
 * @return 当前对象
 */
VLFlag& VLFlag::operator +(const char* flag) {
	this->operator+=(flag);
	return *this;
}

/**
 * @Author: CimZzz
 * @Date: 2022-10-25 16:56:32
 * 
 * 重载加法运算
 * 
 * @param flag 标志对象
 * 
 * @return 当前对象
 */
VLFlag& VLFlag::operator +(const VLFlag& flagObj) {
	this->operator+=(flagObj);
	return *this;
}

/**
 * @Author: CimZzz
 * @Date: 2022-10-25 16:56:32
 * 
 * 重载加法运算
 * 
 * @param propPtr 属性指针
 * 
 * @return 当前对象
 */
VLFlag& VLFlag::operator +(const std::shared_ptr<VLProp>& propPtr) {
	this->operator+=(propPtr);
	return *this;
}

/**
 * @Author: CimZzz
 * @Date: 2022-10-25 17:17:03
 * 
 * 重载加等运算
 * 
 * @param flag 标志
 */
void VLFlag::operator +=(const char * flag) {
	if(flag == nullptr) {
		return;
	}
	std::string flagStr(flag);
	if(flagStr.empty()) {
		return;
	}
	if(this->uniqueSet.find(flagStr) == this->uniqueSet.end()) {
		this->uniqueSet.insert(flagStr);
		this->concatFlag(flagStr);
	}
}

/**
 * @Author: CimZzz
 * @Date: 2022-10-25 17:17:03
 * 
 * 重载加等运算
 * 
 * @param flag 标志
 */
void VLFlag::operator +=(const std::string& flag) {
	if(flag.empty()) {
		return;
	}
	if(this->uniqueSet.find(flag) == this->uniqueSet.end()) {
		this->uniqueSet.insert(flag);
		this->concatFlag(flag);
	}
}

/**
 * @Author: CimZzz
 * @Date: 2022-10-25 17:17:03
 * 
 * 重载加等运算
 * 
 * @param flagObj 标志对象
 */
void VLFlag::operator +=(const VLFlag& flagObj) {
	for(auto iter = flagObj.uniqueSet.begin() ; iter != flagObj.uniqueSet.end() ; iter ++) {
		if(this->uniqueSet.find(*iter) == this->uniqueSet.end()) {
			this->uniqueSet.insert(*iter);
			this->concatFlag(*iter);
		}
	}
}

/**
 * @Author: CimZzz
 * @Date: 2022-10-25 17:17:03
 * 
 * 重载加等运算
 * 
 * @param propPtr 属性指针
 */
void VLFlag::operator +=(const std::shared_ptr<VLProp>& propPtr) {
	if(propPtr.get() == nullptr)  {
		return;
	}
	if(propPtr->isNode()) {
		this->operator+=(propPtr->getValue());
	} else if(propPtr->isArray()) {
		auto arrayPropPtr = (ArrayProp *) propPtr.get();
		for(auto iter = arrayPropPtr->begin() ; iter != arrayPropPtr->end() ; iter ++) {
			this->operator+=(iter->get()->getValue());
		}
		
	}
}

/**
 * @Author: CimZzz
 * @Date: 2022-10-25 17:36:13
 * 
 * 判断当前标志是否为空
 */
bool VLFlag::empty() const {
	return this->flagStr.empty();
}

/**
 * @Author: CimZzz
 * @Date: 2022-10-25 18:27:50
 * 
 * 转换为属性对象指针
 * 
 * @return 属性对象指针
 */
std::shared_ptr<VLProp> VLFlag::asProp() {
	if(this->uniqueSet.empty()) {
		return std::shared_ptr<VLProp>(nullptr);
	}
	if(this->uniqueSet.size() == 1) {
		return std::shared_ptr<VLProp>(new NodeProp(this->flagStr));
	}
	ArrayProp* arrayPropPtr = new ArrayProp();
	for(auto iter = this->uniqueSet.begin() ; iter != this->uniqueSet.end() ; iter ++) {
		arrayPropPtr->add(*iter);
	}
	return std::shared_ptr<VLProp>(arrayPropPtr);
}

/**
 * @Author: CimZzz
 * @Date: 2022-10-25 17:08:46
 * 
 * 拼接标志字符串
 * 
 * @param flag 标志
 */
void VLFlag::concatFlag(const std::string& flag) {
	bool isFirst = this->flagStr.empty();
	if(isFirst) {
		this->flagStr = flag;
	} else {
		this->flagStr += this->separator + flag;
	}
}